#ifndef LEX_H
#define LEX_H
#include "interpreter.h"
class Lex {
public:
    struct ReservedWord {
        const char *word;
        LexToken token;
    };

    Lex();
    /* initialize the lexer */
    static void LexInit(Interpreter *pc);

    /* deallocate */
    static void LexCleanup(Interpreter *pc);

    /* lexically analyse some source text */
    static void *LexAnalyse(Interpreter *pc, const char *fileName, const char *Source,
                     int SourceLen, int *TokenLen);

    /* prepare to parse a pre-tokenised buffer */
    static void LexInitParser(Interpreter *pc, ParseState *parser, const char *sourceText,
                       void *TokenSource, char *fileName, int RunIt, int EnableDebugger);

#if 0 /* useful for debug */
    static void LexPrintToken(LexToken token);
#endif

    /* get the next token given a parser state, pre-processing as we go */
    static LexToken LexGetToken(ParseState *parser, Value **Value,
                         int IncPos);

    /* take a quick peek at the next token, skipping any pre-processing */
    static LexToken LexRawPeekToken(ParseState *parser);

    /* find the end of the line */
    static void LexToEndOfMacro(ParseState *parser);

    /* copy the tokens from StartParser to EndParser into new memory, removing
        TokenEOFs and terminate with a kTokenEndOfFunction */
    static void *LexCopyTokens(ParseState *StartParser, ParseState *EndParser);

    /* indicate that we've completed up to this point in the interactive input
        and free expired tokens */
    static void LexInteractiveClear(Interpreter *pc, ParseState *parser);

    /* indicate that we've completed up to this point in the interactive
        input and free expired tokens */
    static void LexInteractiveCompleted(Interpreter *pc, ParseState * parser);

    /* the next time we prompt, make it the full statement prompt */
    static void LexInteractiveStatementPrompt(Interpreter *pc);
private:
    /* check if a word is a reserved word - used while scanning */
    static LexToken LexCheckReservedWord(Interpreter *pc, const char *word);
    /* get a numeric literal - used while scanning */
    static LexToken LexGetNumber(Interpreter *pc, LexState *Lexer, Value *Value);
    /* get a reserved word or identifier - used while scanning */
    static LexToken LexGetWord(Interpreter *pc, LexState *Lexer, Value *Value);
    /* unescape a character from an octal character constant */
    static unsigned char LexUnEscapeCharacterConstant(const char **From,
                                                      unsigned char FirstChar, int base);
    /* unescape a character from a string or character constant */
    static unsigned char LexUnEscapeCharacter(const char **From, const char *end);
    /* get a string constant - used while scanning */
    static LexToken LexGetStringConstant(Interpreter *pc, LexState *Lexer,
                                         Value *Value, char EndChar);
    /* get a character constant - used while scanning */
    static LexToken LexGetCharacterConstant(Interpreter *pc, LexState *Lexer,
                                            Value *Value);
    /* skip a comment - used while scanning */
    static void LexSkipComment(LexState *Lexer, char NextChar);
    /* skip a line continuation - used while scanning */
    static void LexSkipLineCont(LexState *Lexer, char NextChar);
    /* get a single token from the source - used while scanning */
    static LexToken LexScanGetToken(Interpreter *pc, LexState *Lexer,
                                    Value **Value);
    /* what size value goes with each token */
    static int LexTokenSize(LexToken token);
    /* produce tokens from the lexer and return a heap buffer with
    the result - used for scanning */
    static void *LexTokenize(Interpreter *pc, LexState *Lexer, int *TokenLen);
    /* get the next token, without pre-processing */
    static LexToken LexGetRawToken(ParseState *parser, Value **Value,
                                   int IncPos);
    /* correct the token position depending if we already incremented the position */
    static void LexHashIncPos(ParseState *parser, int IncPos);
    /* handle a #ifdef directive */
    static void LexHashIfdef(ParseState *parser, int IfNot);
    /* handle a #if directive */
    static void LexHashIf(ParseState *parser);
    /* handle a #else directive */
    static void LexHashElse(ParseState *parser);
    /* handle a #endif directive */
    static void LexHashEndif(ParseState *parser);
    static const ReservedWord kReservedWords[];
    //Interpreter *pc;
};
#endif //LEX_H
